<template>
  <div class="user-container">
    <!-- 左侧通讯录树结构区 -->
    <div class="left" ref="leftRef">
      <!-- 顶部搜索框和创建群组按钮 -->
      <!-- @keyup.enter监听回车事件 -->
      <div class="search-box">
        <el-input
          clearable
          placeholder="搜索"
          :prefix-icon="Search"
          v-model="treeKw"
        />
        <div class="create-group" @click="createGroupComponentVisible = true">
          <el-icon><Plus/></el-icon>
        </div>
      </div>

      <!-- 提示 -->
      <div v-if="UserState.loginUser.admin" class="tip-box">
        <strong>*右键点击节点进行新增或删除*</strong>
      </div>

      <!-- 树结构区 -->
      <div class="tree-box beautify-scrollbar">
        <el-tree
          ref="treeRef"
          :data="treeData"
          :highlight-current="true"
          :expand-on-click-node="true"
          :props="{label:'text',children:'childList'}"
          node-key="id"
          :default-expanded-keys="defaultExpandedKeys"
          :default-expand-all="false"
          :filter-node-method="filterTree"
          @node-click="handleTreeNodeClick"
          @node-contextmenu="rightClickHandle"
        >
          <!-- 自定义显示节点内容，node表示节点对象，data表示节点数据 -->
          <template #default="{ node, data }">
            <!-- @contextmenu监听右键点击事件，.prevent阻止浏览器原来的默认的弹出 -->
            <!-- <div class="custom-tree-node" @contextmenu.prevent="handleContextMenu($event,data)"> -->
            <!-- 此处改成 el-tree 组件中提供的 node-contextmenu 属性 -->
            <div class="custom-tree-node">
              <div class="icon">
                <!-- 是部门节点就Folder图标 -->
                <el-icon v-if="data.nodeType === 1" :size="18"><Folder/></el-icon>
                <!-- 是用户节点就加头像 -->
                <!-- <el-avatar v-if="data.nodeType === 2 && data.val.avatar" shape="square" :src="data.val.avatar" :size="20"/> -->
                <!-- 是用户节点且没有设置头像的就放UserFilled图标作为默认头像 -->
                <!-- <el-avatar v-if="data.nodeType === 2 && !data.val.avatar" shape="square" :size="20"> -->
                  <!-- <el-icon ><UserFilled/></el-icon> -->
                <!-- </el-avatar> -->
                <lc-avatar v-if="data.nodeType === 2" :src="data.val.avatar"/>
              </div>
              <!-- 节点名称 -->
              <div class="text">{{ node.label }}</div>
            </div>
          </template>
        </el-tree>
      </div>
    </div>

    <!-- 左侧left区拖拽mousedown事件绑定DOM -->
    <div class="resizer" @mousedown="startResize"></div>

    <!-- 右侧详情区 -->
    <div class="right">
      <!-- 部门节点详情 -->
      <div v-if="clickedTreeNode && clickedTreeNode.nodeType === 1" class="node-detail">
          <div class="detail-item">
            {{ clickedTreeNode.text }}
          </div>
          <div class="detail-item">
            - {{ clickedTreeNode.userCount }}人
          </div>
      </div>

      <!-- 用户节点详情 -->
      <div v-if="clickedTreeNode && clickedTreeNode.nodeType === 2" class="node-detail">
        <!-- 头像 -->
        <div class="detail-item">
          <el-avatar shape="square" :size="150" fit="cover" :src="clickedTreeNode.val.avatar">
            <img src="/img/default-avatar.jpg">
          </el-avatar>
        </div>
        <!-- 姓名 -->
        <div class="detail-item">
          <strong>{{ clickedTreeNode.val.username }}</strong>
        </div>
        <!-- 部门 -->
        <div class="detail-item">
          {{ clickedTreeNode.val.deptName }}
        </div>
        <!-- 岗位 -->
        <div class="detail-item">
          {{ clickedTreeNode.val.job ? clickedTreeNode.val.job : '-' }}
        </div>
        <!-- 按钮 -->
        <div class="detail-item">
          <el-button type="primary" size="small" @click="createPrivateRoom">发消息</el-button>
        </div>
      </div>
    </div>

    <!-- 通讯录节点右键点击自定义菜单 -->
    <div v-if="menuVisible" 
         :style="{ top: `${menuPosition.y}px`, left: `${menuPosition.x}px` }" 
         class="custom-menu">
      <!-- 右击的节点是部门节点时 -->
      <ul v-if="rightClickNode.nodeType === 1">
        <li @click="addDept(rightClickNode)">新增部门</li>
        <li @click="addUser(rightClickNode)">新增用户</li>
        <li @click="delDept(rightClickNode)">删除部门</li>
      </ul>
      <!-- 右击的节点是用户节点时 -->
      <ul v-if="rightClickNode.nodeType === 2">
        <li @click="delUser(rightClickNode)">删除用户</li>
      </ul>
    </div>

    <!-- 新增部门对话框 -->
    <el-dialog
        v-model="openAddDeptDialog"
        title="新增部门"
        width="400"
        @close="closedAddDeptDialog"
    >
        <!-- 主体内容区域 -->
        <div class="edit-box">
          <div class="edit-item">
            <div class="item-label">
              上级部门：
            </div>
            <div class="item-value">
              <el-input size="small" v-model="addDeptParam.parentName" disabled/>
            </div>
          </div>
          <div class="edit-item">
            <div class="item-label">
              部门名称：
            </div>
            <div class="item-value">
              <el-input size="small" v-model="addDeptParam.name" clearable placeholder="请输入部门名称"/>
            </div>
          </div>
        </div>

        <!-- 底部按钮区域 -->
        <template #footer>
            <div class="dialog-footer">
                <el-button size="small" type="primary" @click="doSubmitAddDept">确定</el-button>
            </div>
        </template>
    </el-dialog>

    <!-- 新增用户对话框 -->
    <el-dialog
        v-model="openAddUserDialog"
        title="新增用户"
        width="400"
        @close="closedAddUserDialog"
    >
        <!-- 主体内容区域 -->
        <div class="edit-box">
          <div class="edit-item">
            <div class="item-label">
              所属部门：
            </div>
            <div class="item-value">
              <el-input size="small" v-model="addUserParam.deptName" disabled/>
            </div>
          </div>
          <div class="edit-item">
            <div class="item-label">
              用户名称：
            </div>
            <div class="item-value">
              <el-input size="small" v-model="addUserParam.username" clearable placeholder="请输入用户名称"/>
            </div>
          </div>
          <div class="edit-item">
            <div class="item-label">
              用户职位：
            </div>
            <div class="item-value">
              <el-input size="small" v-model="addUserParam.job" clearable placeholder="请输入用户职位"/>
            </div>
          </div>
        </div>

        <!-- 底部按钮区域 -->
        <template #footer>
            <div class="dialog-footer">
                <el-button size="small" type="primary" @click="doSubmitAddUser">确定</el-button>
            </div>
        </template>
    </el-dialog>

    <!-- 创建群聊 -->
    <edit-group v-model:visible="createGroupComponentVisible"/>

  </div>
</template>

<script setup>
// 导入
import { ref,onMounted,watch } from 'vue'
import { Search,Plus,Folder,UserFilled } from '@element-plus/icons-vue';
import { $msg_e,$msg_s,$msg_i } from '../utils/msg.js'
import { $get,$post } from '../utils/request.js'
import { UserState } from '../store/loginUser.js'
import { ElMessageBox } from 'element-plus'
import EditGroup from './EditGroup.vue'
import { DeptApi,RoomApi,UserApi } from '@/api/path.js';
import LcAvatar from './LcAvatar.vue';
import { RoomState } from '@/store/currentRoom.js';
import { useRouter } from 'vue-router';


// 初始化
const router = useRouter()



// 数据
const treeData = ref([]) // 通讯录树数据
const treeRef = ref(); // 树结构对象引用
const clickedTreeNode = ref({}) // 左键点击的节点
const treeKw = ref('') // 通讯录搜索关键词
const defaultExpandedKeys = ref(['01']) // 默认展开的节点Id列表
const menuVisible = ref(false); // 控制右键菜单显示
const menuPosition = ref({ x: 0, y: 0 }); // 记录右键菜单位置
const rightClickNode = ref({}); // 右键点击的通讯录节点
const addDeptParam = ref({
  parentId:'',
  parentName:'',
  name:''
})
const openAddDeptDialog = ref(false)
const addUserParam = ref({
  username:'',
  deptId:'',
  deptName:'',
  job:''
})
const openAddUserDialog = ref(false)
const leftRef = ref(null); // left区DOM引用对象
let isResizing = false;
let initialWidth = 0;
let initialX = 0;
const createGroupComponentVisible = ref(false)


// 函数
const getContactBookData = async () => { // 获取通讯录数据
  const res = await $get(UserApi.getContactBook)
  // console.log('getContactBookData-res: ', res);
  if(!res.success){
    return $msg_e(res.message)
  }
  treeData.value = res.data
}
const filterTree = (value, tree) => { // 过滤树
  if (!value) return true
  return tree.text.includes(value)
}
const closedAddDeptDialog = () => {
  addDeptParam.value.name = '';
  addDeptParam.value.parentId = '';
  addDeptParam.value.parentName = '';
}
const handleTreeNodeClick = async treeNode => {
    console.log('clickedTreeNode: ', treeNode);
    clickedTreeNode.value = treeNode
    // 查询部门用户计数
    if(treeNode && treeNode.nodeType === 1){
      const res = await $get(UserApi.count,{deptId:treeNode.id})
      console.log('userCount-res:',res);
      if(!res.success){
        return $msg_e(res.message)
      }
      // 添加用户计数属性
      clickedTreeNode.value.userCount = res.data
    }

    // 查询所属部门名称
    if(treeNode && treeNode.nodeType === 2){
      const res = await $get(DeptApi.getDetail,{id:treeNode.parentId})
      // console.log('userDept-res:',res);
      if(!res.success){
        return $msg_e(res.message)
      }
      // 添加用户计数属性
      clickedTreeNode.value.val.deptName = res.data.name
    }
}
const rightClickHandle = (event,data,node,tree) => { // 当某一节点被鼠标右键点击时会触发该事件
  // console.log('rightClickHandle:',event,data,node,tree);
  // 共四个参数，依次为：event、传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身
  handleContextMenu(event,data)
}
const handleContextMenu = (event,data) => { // 通讯录树节点右键点击事件
  // console.log('handleContextMenu-event:',event);
  // console.log('handleContextMenu-data:',data);
  if(!UserState.loginUser.admin){
    return;
  }
  menuPosition.value = {
    x: event.clientX,
    y: event.clientY,
  };
  menuVisible.value = true;
  rightClickNode.value = data
}
const addDept = parentNode => {
  // console.log('addDept-parentDept:', parentNode);
  addDeptParam.value.parentId = parentNode.id;
  addDeptParam.value.parentName = parentNode.text;
  openAddDeptDialog.value = true
  closeMenu()
}
const doSubmitAddDept = async () => {
  if(!addDeptParam.value.name){
    return $msg_e('部门名称不能为空')
  }
  const res = await $post(DeptApi.add,addDeptParam.value);
  // console.log('addDept-res:',res);
  if(!res.success){
    return $msg_e(res.message)
  }
  $msg_s('新增部门成功')
  
  // 刷新树
  getContactBookData()
  // 设置默认展开
  defaultExpandedKeys.value = [addDeptParam.value.parentId]

  openAddDeptDialog.value = false
}
const addUser = parentNode => {
  // console.log('addUser-parentDept:', parentNode);
  addUserParam.value.deptId = parentNode.id;
  addUserParam.value.deptName = parentNode.text;
  openAddUserDialog.value = true
  closeMenu()
}
const closedAddUserDialog = () => {
  addUserParam.value.username = '';
  addUserParam.value.deptId = '';
  addUserParam.value.deptName = '';
  addUserParam.value.job = '';
}
const doSubmitAddUser = async () => {
  if(!addUserParam.value.username){
    return $msg_e('用户名称不能为空')
  }
  // 设置默认密码
  const res = await $post(UserApi.add,addUserParam.value)
  // console.log('addUser-res:',res);
  if(!res.success){
    return $msg_e(res.message)
  }
  $msg_s('新增用户成功')
  
  // 刷新树
  getContactBookData();
  defaultExpandedKeys.value = [addUserParam.value.deptId]

  openAddUserDialog.value = false
}
const delDept = data => {
  closeMenu()
  // console.log('delDept-data:', data);
  ElMessageBox.confirm(
      '此操作将永久删除部门, 是否操作?',
      '提示',
      {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning',
      }
  ).then(async () => {
      // 点击"确认"按钮的回调
      const res = await $post(DeptApi.delByIds,[data.id])
      if(res.success){
          $msg_s('删除部门成功')
          // 刷新树
          getContactBookData();
          defaultExpandedKeys.value = [data.parentId]
      }else{
          $msg_e(res.message)
      }
          
  })
  .catch(() => {
      // 点击"取消"按钮的回调
      $msg_i('已取消删除')
  })

}
const delUser = data => {
  // console.log('delUser-data:', data);
  closeMenu()
  ElMessageBox.confirm(
      '此操作将永久删除用户, 是否操作?',
      '提示',
      {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning',
      }
  ).then(async () => {
      // 点击"确认"按钮的回调
      const res = await $post(UserApi.delByIds,[data.id])
      if(res.success){
          $msg_s('删除用户成功')
          // 刷新树
          getContactBookData();
          defaultExpandedKeys.value = [data.parentId]
      }else{
          $msg_e(res.message)
      }
          
  })
  .catch(() => {
      // 点击"取消"按钮的回调
      $msg_i('已取消删除')
  })
}

// 关闭菜单
const closeMenu = () => {
  menuVisible.value = false;
};

// 鼠标按下-开始拖拽宽度
const startResize = (e) => {
    isResizing = true;
    initialX = e.clientX; // 鼠标相对与浏览器左上角的x坐标
    initialWidth = leftRef.value.offsetWidth; // 获取元素的布局宽度（包括内边距、边框和垂直滚动条，但不包括外边距）
    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('mouseup', stopResize);
};

// 鼠标移动事件
const onMouseMove = (e) => {
    if (isResizing) {
        const deltaX = e.clientX - initialX;
        let newWidth = initialWidth + deltaX;
        // 限制最小宽度
        newWidth = newWidth < 200 ? 200 : (newWidth > 400 ? 400 : newWidth)
        leftRef.value.style.width = `${newWidth}px`;
    }
};

// 鼠标放开-停止拖拽宽度
const stopResize = () => {
    isResizing = false;
    document.removeEventListener('mousemove', onMouseMove);
    document.removeEventListener('mouseup', stopResize);
};

// 创建私聊聊天室
const createPrivateRoom = async () => {
  console.log('createPrivateRoom: ', clickedTreeNode.value);
  const res = await $post(RoomApi.createRoom,[clickedTreeNode.value.id]);
  console.log('createPrivateRoom-res: ', res);
  if(!res.success){
    return $msg_e(res.message)
  }
  // 跳转Chat页面
  RoomState.setCurrentRoom(res.data)
  router.push('/home/chat')
}




// 侦听器
watch(treeKw, newVal => {
  // console.log('treeKw-newVal:',newVal);
  if (treeRef.value) {
      // filter方法：接收一个参数并指定为 filter-node-method 属性的第一个参数
      treeRef.value.filter(newVal); // 直接访问，不使用非空断言
  }
})



// 声明周期
onMounted(() => {
  // 点击页面其他地方关闭菜单
  document.addEventListener('click', closeMenu);
  getContactBookData()
})

</script>

<style scoped lang="scss">
.user-container{
  height: 100%;
  display: flex;
  flex-direction: row;
  overflow: hidden; /**限制外层容器在垂直和水平方向都不能出现滚动条 */
  & > .left{
    width: 200px; /**初始化宽度 */
    // border-right: 1px solid #e2e1e4; /**使用class为resizer的div表示 */
    padding: 5px;
    box-sizing: border-box; /**这个box-sizing是配合padding使用，不然整个屏幕会出现竖向滚动条 */
    display: flex;
    flex-direction: column;
    user-select: none; /**禁止DOM内容被选中及其兼容设置 */
    -webkit-user-select: none; /* Chrome, Safari */
    -moz-user-select: none; /* Firefox */
    -ms-user-select: none; /* Internet Explorer */
    & > .search-box{
      margin-bottom: 10px;
      display: flex;
      flex-direction: row;
      & > .el-input{
        flex: 1;
      }
      & > .create-group{
        width: 32px;
        height: 32px;
        border-radius: 2px;
        margin-left: 6px;
        background-color: #E5E5E7;
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: pointer;
        & > .el-icon{
          font-size: 16px;
        }
      }
      & > .create-group:hover{
        background-color: #CFD0D2;
      }
    }
    & > .tip-box{
      text-align: center;
      color: red;
      font-size: 12px;
      margin-bottom: 4px;
    }
    & > .tree-box{
      flex: 1;
      // 提取到App.vue中作为公共样式，只要使用beautify-scrollbar类即可
      // overflow-y: auto;
      // &::-webkit-scrollbar{
      //     width: 4px; /* 设置滚动条的宽度 */
      //     height: 4px; /* 设置滚动条的高度 */
      // }
      // &::-webkit-scrollbar-thumb {
      //     background-color: #DCDCDC; /* 设置滚动条滑块的颜色 */
      //     border-radius: 4px; /* 设置滚动条滑块的圆角 */
      // }
      // &::-webkit-scrollbar-track {
      //     background-color: #fff; /* 设置滚动条轨道的颜色 */
      //     border-radius: 4px; /* 设置滚动条轨道的圆角 */
      // }
      & .custom-tree-node{
        font-size: 16px;
        display: flex;
        flex-direction: row;
        align-items: center;
        & > .icon{
          display: flex;
          justify-content: center;
          align-items: center;
          & > .el-icon{
            margin-right: 4px;
            color: #3975C6;
          }
          // 改成使用封装的组件<lc-avatar>
          // & > .el-avatar{
          //   margin-right: 4px;
          //   --el-avatar-bg-color:#83B7F7;
          //   & > .el-icon{
          //     color: #fff;
          //   }
          // }
          & > .lc-avatar{
            margin-right: 4px;
          }
        }
        & > .text{
          flex: 1;
        }
        
      }
    }
  }
  // 使用App.vue中的统一样式
  // & > .resizer{
  //   width: 4px;/**设定一个宽度是为了容易让鼠标容易放到上面 */
  //   border-left: 1px solid #e2e1e4;
  //   cursor: ew-resize; /**显示表示水平拖动的左右箭头 */
  // }
  & > .right{
    flex: 1;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: start; /**靠顶部 */
    & > .node-detail{
      font-size: 16px;
      margin-top: 100px;
      display: flex;
      flex-direction: column;
      & > .detail-item{
        text-align: center;
        margin-bottom: 10px;
      }
    }
  }
}

/**通讯录节点右键点击弹出菜单样式 */
.custom-menu {
  position: absolute;
  background-color: #E5E5E7;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.1);
  z-index: 9999; /**设置DOM在z轴上的堆叠顺序，当且只当DOM设置了position属性才有效 */
  & > ul{
    list-style: none;
    padding: 0;
    margin: 0;
    & > li{
      padding: 8px 10px;
      cursor: pointer;
    }
    & > li:hover{
      background-color: #CFD0D2;
    }
  }
}

</style>